import { isEmpty, isFunction } from '@/utils/is';
import { ref, unref } from 'vue';
export const useTableValidate = (allProps: any) => {
    const validSuccess = ref(true); // 检测结果
    const validErrors = ref<any[]>([]); // 错误数据
    const firstErrCol = ref<any>({}); // 第一次校验错误数据
    /**
     * 验证每一列的数据
     * @param {*} rules 某一单元格属性的验证规则
     * @param {*} column 某一单元格数据
     * @return {*} 返回单元格验证的promise
     */
    const validateCell = (rules: any, column: any, rowIndex: number) => {
        const errors: any = [];
        const syncValidators: any = [];
        if (rules && rules.length) {
            rules.forEach((item: any) => {
                // 校验是否为空
                if (item.required && isEmpty(column)) {
                    errors.push(item);
                    if (unref(validSuccess)) {
                        validSuccess.value = false;
                    }
                }
                // 校验是否有自定义函数，有就插入队列中
                if (item.validator && isFunction(item.validator)) {
                    const validRes = item.validator(rules, column, rowIndex).catch(() => {
                        errors.push(item);
                        if (unref(validSuccess)) {
                            validSuccess.value = false;
                        }
                    });
                    syncValidators.push(validRes);
                }
            });
        }
        // 执行队列
        return Promise.all(syncValidators).then(() => {
            return Promise.reject(errors);
        });
    };
    /**
     * 验证表格所有数据
     * @return {*} 返回promise
     */
    const validate = (): Promise<any> => {
        const { 'data-source': list, rules } = unref(allProps);
        // rules所有列属性的验证规则
        validSuccess.value = true;
        validErrors.value = [];
        const rowErrors: any = []; //存放每一行校验的结果
        list.forEach((row: any, rowIndex: number) => {
            const colErrors: any = []; //存放每一列校验的结果
            Object.keys(row).forEach((field, columnIndex) => {
                // 如果已经有错误，则无需继续验证
                if (unref(validSuccess)) {
                    // 如果存在验证规则
                    if (rules[field]) {
                        colErrors.push(
                            validateCell(rules[field], row[field], rowIndex).catch((err) => {
                                validErrors.value[rowIndex] = validErrors.value[rowIndex] || [];
                                validErrors.value[rowIndex][field] = err;
                                if (err.length) {
                                    const rest = {
                                        message: err[0].message, //将捕捉的第一条作为message字段
                                        rule: err[0],
                                        rules: rules,
                                        rowIndex,
                                        row: row,
                                        column: field,
                                        columnIndex
                                    };
                                    return Promise.reject(rest);
                                }
                            })
                        );
                    }
                }
            });
            rowErrors.push(Promise.all(colErrors));
        });
        return Promise.all(rowErrors)
            .then(() => {
                // 验证通过
                firstErrCol.value = {};
                return true;
            })
            .catch((err) => {
                // 验证失败
                firstErrCol.value = err;
            });
    };
    const validateRow = (row, rowIndex) => {
        const { rules } = unref(allProps);
        // rules所有列属性的验证规则
        validSuccess.value = true;
        validErrors.value = []; // 清空错误数据
        const rowErrors: any = []; //存放每一行校验的结果
        const colErrors: any = []; //存放每一列校验的结果
        Object.keys(row).forEach((field, columnIndex) => {
            // 如果已经有错误，则无需继续验证
            if (unref(validSuccess)) {
                // 如果存在验证规则
                if (rules[field]) {
                    colErrors.push(
                        validateCell(rules[field], row[field], rowIndex).catch((err) => {
                            validErrors.value[rowIndex] = validErrors.value[rowIndex] || [];
                            validErrors.value[rowIndex][field] = err;
                            if (err.length) {
                                const rest = {
                                    message: err[0].message, //将捕捉的第一条作为message字段
                                    rule: err[0],
                                    rules: rules,
                                    rowIndex,
                                    row: row,
                                    column: field,
                                    columnIndex
                                };
                                return Promise.reject(rest);
                            }
                        })
                    );
                }
            }
        });
        rowErrors.push(Promise.all(colErrors));
        return Promise.all(rowErrors)
            .then(() => {
                // 验证通过
                firstErrCol.value = {};
                return true;
            })
            .catch((err) => {
                // 验证失败
                firstErrCol.value = err;
            });
    };
    /**
     * 验证当前单元格是否有报错信息
     * @param {*} record 某一行数据
     * @param {*} field 某一单元格字段名称
     * @return {*} 返回true/false
     */
    const hasError = (record: any, field: string) => {
        if (!unref(validSuccess)) {
            return unref(firstErrCol).row === record && unref(firstErrCol).column === field;
        } else {
            return false;
        }
    };
    /**
     * 动态设置tooltip属性
     * @param {*} record 某一行数据
     * @param {*} field 某一单元格字段名称
     * @return {*} 返回属性集合
     */
    const buildValidateTooltipProps = (record: any, field: string) => {
        const props: any = {
            title: unref(firstErrCol).message,
            autoAdjustOverflow: true,
            arrowPointAtCenter: true,
            color: 'red',
            getPopupContainer: (node: any) => node.parentNode
        };
        props['visible'] = hasError(record, field);
        return props;
    };
    return { validate, validateRow, hasError, buildValidateTooltipProps };
};